package com.wlsmartlock.Fragments;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.Toast;

import com.google.gson.Gson;

import com.wlsmartlock.Activitys.MainActivity;
import com.wlsmartlock.Beans.MqttArgBean;
import com.wlsmartlock.Beans.MqttBean;
import com.wlsmartlock.Beans.MqttDataBean;
import com.wlsmartlock.Beans.MqttLogBean;
import com.wlsmartlock.Beans.MqttValueBean;
import com.wlsmartlock.BleUnit.BleService;
import com.wlsmartlock.MqttUnit.MqttService;
import com.wlsmartlock.R;
import com.wlsmartlock.Utils.App;
import com.wlsmartlock.Utils.ByteUtils;
import com.wlsmartlock.Utils.DeviceListAdapter;
import com.wlsmartlock.Utils.SystemUtil;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import static android.support.constraint.Constraints.TAG;


public class BleFragment extends Fragment {
    private final int REQUEST_ENABLE_BT = 1;
    private boolean mScanning = false;
    private View view;
    private RecyclerView rvDeviceList;
    private FloatingActionButton bleButton;
    private BleService mBleService;

    private BluetoothAdapter mBtAdapter;
    private DeviceListAdapter mDeviceListAdapter;
    private List<BluetoothDevice> mBluetoothDeviceList;
    private List<String> mRssiList;
    private String keysn = "";
    private boolean isreading = false;
    private boolean isregister = false;
    private int readmetry = 3000;
    private UUID[] discover_uuid = {UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e")};
    private byte[] recv = new byte[1024];
    private int recvoffset = 0;
    private MyTimerTask mTimerTask;
    Timer timer = new Timer();

    /*TimerTask task = new TimerTask() {
        @Override
        public void run() {
            if(isreading){
                if(readmetry < 0){
                    isreading = false;
                    readmetry = 3000;
                    Message msg = new Message();
                    msg.obj = 101;
                    handler.sendMessage(msg);
                }else{
                    readmetry -= 100;
                }

            }
        }
    };*/

    Handler handler = new Handler(){
        public void handleMessage(Message msg){
            switch(msg.what){
                case 101:
                    Toast.makeText(getActivity(), "接收数据超时", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    public BleFragment() {
        // Required empty public constructor
    }

    public static BleFragment newInstance() {
        BleFragment fragment = new BleFragment();

        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_ble, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        rvDeviceList = view.findViewById(R.id.rv_device_list);
        bleButton = (FloatingActionButton) view.findViewById(R.id.fab);
        //mQttService = ((MqttService.LocalBinder) rawBinder).getService();
        if(timer == null){
            timer = new Timer();
            mTimerTask = new MyTimerTask();
            timer.schedule(mTimerTask,0,100);
        }

        bleButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                if(!mScanning){
                    initBle();
                    initData();
                }
            }
        });

        initBle();
        initData();
        if(isregister == false){
            registerBleReceiver();
        }


    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        super.onActivityResult(requestCode,resultCode,intent);

    }

    /**
     * 初始化数据
     */
    private void initData() {
        // 蓝牙设备列表
        mBluetoothDeviceList = new ArrayList<>();
        // 蓝牙设备RSSI列表
        mRssiList = new ArrayList<>();
        mDeviceListAdapter = new DeviceListAdapter(mBluetoothDeviceList, mRssiList);
        rvDeviceList.setLayoutManager(new LinearLayoutManager(getActivity()));
        rvDeviceList.setAdapter(mDeviceListAdapter);

        // 连接蓝牙设备
        mDeviceListAdapter.setOnItemClickListener(new DeviceListAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                if(App.mConnectionState > 0){
                    Toast.makeText(getActivity(), "已有设备连接，请先断开设备", Toast.LENGTH_SHORT).show();
                    return;
                }else{
                    Toast.makeText(getActivity(), "开始连接", Toast.LENGTH_SHORT).show();
                }

                mBtAdapter.stopLeScan(mLeScanCallback);
                mBleService.connect(mBtAdapter, mBluetoothDeviceList.get(position).getAddress());
                keysn = mBluetoothDeviceList.get(position).getAddress().replaceAll(":","");
            }
        });
    }

    /**
     * 初始化蓝牙
     */
    private void initBle() {
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBtAdapter == null) {
            Toast.makeText(getActivity(), "蓝牙不可用", Toast.LENGTH_LONG).show();
            return;
        }

        if (!mBtAdapter.isEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_ENABLE_BT);
            return;
        }

        // 搜索蓝牙设备
        scanBleDevice();
    }

    /**
     * 搜索蓝牙设备回调
     */
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
            if (!mBluetoothDeviceList.contains(bluetoothDevice)) {
                mBluetoothDeviceList.add(bluetoothDevice);
                mRssiList.add(String.valueOf(i));
                mDeviceListAdapter.notifyDataSetChanged();
            }
        }
    };

    /**
     * 搜索蓝牙设备
     */
    private void scanBleDevice() {
        mScanning = true;
        mBtAdapter.startLeScan(discover_uuid,mLeScanCallback);
        // 搜索5s
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mScanning = false;
                mBtAdapter.stopLeScan(mLeScanCallback);
            }
        }, 5000);
    }

    /**
     * 注册蓝牙信息接收器
     */
    private void registerBleReceiver() {
        // 绑定服务
        Intent intent = new Intent(getActivity(), BleService.class);
        getActivity().bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        getActivity().startService(intent);

        // 注册蓝牙信息广播接收器
        IntentFilter filter = new IntentFilter();
        filter.addAction(BleService.ACTION_GATT_CONNECTED);
        filter.addAction(BleService.ACTION_GATT_DISCONNECTED);
        filter.addAction(BleService.ACTION_GATT_SERVICES_DISCOVERED);
        filter.addAction(BleService.ACTION_DATA_AVAILABLE);
        filter.addAction(BleService.ACTION_CONNECTING_FAIL);
        App.mBleReceiver = new BleReceiver();
        getActivity().registerReceiver(App.mBleReceiver, filter);
        isregister = true;
    }

    /**
     * 蓝牙信息接收器
     */
    private class BleReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (TextUtils.isEmpty(action)) {
                return;
            }
            switch (action) {
                case BleService.ACTION_GATT_CONNECTED:
                    //Toast.makeText(getActivity(), "蓝牙已连接", Toast.LENGTH_SHORT).show();
                    Log.i(TAG, "蓝牙已连接" );
                    //开始绑定蓝牙钥匙
                    mBleService.sendData(0xc5,"");
                    break;

                case BleService.ACTION_GATT_DISCONNECTED:
                    //Toast.makeText(getActivity(), "蓝牙已断开", Toast.LENGTH_SHORT).show();
                    Log.i(TAG, "蓝牙已断开" );
                    keysn = "";
                    App.mConnectionState = 0;
                    mBleService.release();
                    break;

                case BleService.ACTION_CONNECTING_FAIL:
                    Toast.makeText(getActivity(), "蓝牙已断开", Toast.LENGTH_SHORT).show();
                    App.mConnectionState = 0;
                    keysn = "";
                    mBleService.disconnect();
                    break;

                case BleService.ACTION_DATA_AVAILABLE:
                    byte[] data = intent.getByteArrayExtra(BleService.EXTRA_DATA);
                    parseRes(data);
                    break;

                default:
                    break;
            }
        }
    }

    private void parseRes(byte[] data){
        //Toast.makeText(getActivity(), "蓝牙收到数据", Toast.LENGTH_SHORT).show();
        Log.i("蓝牙", "收到的数据：" + ByteUtils.byteArrayToHexString(data));
        if(isreading){
            System.arraycopy(data,0,recv,recvoffset,data.length);
            recvoffset += data.length;
            byte[] lentotal = new byte[2];
            lentotal[0] = recv[3];
            lentotal[1] = recv[4];
            if(recvoffset == ByteUtils.bytes2long(lentotal) + 5){
                isreading = false;
                byte[] sd = new byte[recvoffset];
                recvoffset = 0;
                System.arraycopy(recv,0,sd,0,sd.length);
                sendMqtt(sd,"BLE_lock_fp");
                recv = new byte[1024];
            }
        }else{
            switch(data[2]){
                case (byte)0xc5:
                    if(data[5] == 0x01){
                        Log.i("蓝牙", "钥匙绑定成功");
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                        mBleService.sendData(0xc4,sdf.format(new Date(System.currentTimeMillis())));
                    }else{
                        Log.i("蓝牙", "钥匙绑定失败");
                    }
                    break;
                case (byte)0xc4:
                    if(data[5] == 0x01){
                        Log.i("蓝牙", "钥匙校时成功");
                    }else{
                        Log.i("蓝牙", "钥匙校时失败");
                    }
                    break;
                case (byte)0xc2:
                    isreading = true;
                    System.arraycopy(data,0,recv,recvoffset,data.length);
                    recvoffset += data.length;
                    byte[] lentotal = new byte[2];
                    lentotal[0] = recv[3];
                    lentotal[1] = recv[4];
                    if(recvoffset == ByteUtils.bytes2long(lentotal) + 5){
                        isreading = false;
                        recvoffset = 0;
                        sendMqtt(recv,"BLE_lock_fp");
                        recv = new byte[1024];
                    }
                    break;
                case (byte)0xc3:
                    byte[] sd = new byte[54];
                    System.arraycopy(data,5,sd,0,54);
                    sendLogMqtt(sd,"BLE_lock_log");
                    break;
                default:
                    isreading = false;
                    break;
            }
        }



    }

    private void sendMqtt(byte[] data,String attr){
        Gson gson = new Gson();
        MqttBean mqbean = new MqttBean();
        mqbean.time = new Date().getTime();
        mqbean.mac = SystemUtil.psuedoID();
        MqttDataBean mqdata = new MqttDataBean();
        MqttValueBean mqval = new MqttValueBean();
        mqval.keysn = keysn;
        mqval.fingerprint = ByteUtils.byteArrayToHexString(data);
        mqdata.value = mqval;
        mqdata.attribute = attr;
        mqbean.data = mqdata;
        MqttService.publish(gson.toJson(mqbean));
    }

    private void sendLogMqtt(byte[] data,String attr){
        Gson gson = new Gson();
        MqttBean mqbean = new MqttBean();
        mqbean.time = new Date().getTime();
        mqbean.mac = SystemUtil.psuedoID();
        MqttDataBean mqdata = new MqttDataBean();
        MqttLogBean mqval = new MqttLogBean();
        mqval.keysn = keysn;
        mqval.log = ByteUtils.byteArrayToHexString(data);
        mqdata.value = mqval;
        mqdata.attribute = attr;
        mqbean.data = mqdata;
        MqttService.publish(gson.toJson(mqbean));
    }

    /**
     * 服务
     */
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder rawBinder) {
            mBleService = ((BleService.LocalBinder) rawBinder).getService();
        }

        public void onServiceDisconnected(ComponentName classname) {
            mBleService = null;
        }
    };

    @Override
    public void onDestroyView() {
        timer.cancel();
        if(mTimerTask != null){
            mTimerTask.cancel();
        }
        timer = null;
        if(isregister){
            isregister = false;
            getActivity().unregisterReceiver(App.mBleReceiver);
            App.mBleReceiver = null;
        }
        super.onDestroyView();
    }

    class MyTimerTask extends TimerTask{
        @Override
        public void run() {
            if(isreading){
                if(readmetry < 0){
                    isreading = false;
                    readmetry = 3000;
                    Message msg = new Message();
                    msg.obj = 101;
                    handler.sendMessage(msg);
                }else{
                    readmetry -= 100;
                }

            }
        }
    }

}


